<?php

namespace App\Http\Controllers\ModelManage;

use App\Http\Controllers\Controller;
use App\Http\Requests\ModelManage\TableRequest;
use App\Models\ModelManage\Database;
use App\Models\ModelManage\Table;
use App\Models\ModelManage\TableField;
use App\Models\ModelManage\TableRelation;
use App\Repositories\ModelManage\TableRepository;
use DB;
use Encore\Admin\Controllers\ModelForm;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Flash;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\MessageBag;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Log;
use Response;

class TableController extends Controller
{
    use ModelForm;

    /** @var  TableRepository */
    private $tableRepository;

    public function __construct(TableRepository $tableRepo)
    {
        $this->tableRepository = $tableRepo;
    }

    /**
     * Display a listing of the Table.
     *
     * @return Response
     */
    public function index()
    {
        return Admin::content(function (Content $content) {

            $content->header(__('model_manage.tables.index_header'));
            $content->description(__('model_manage.tables.index_description'));

            $content->body($this->grid());
        });
    }

    /**
     * Show the form for creating a new Table.
     *
     * @return Response
     */
    public function create()
    {
        return Admin::content(function (Content $content) {

            $content->header(__('model_manage.tables.create_header'));
            $content->description(__('model_manage.tables.create_description'));

            $content->body($this->form());

        });
    }

    /**
     * Store a newly created Table in storage.
     *
     * @param TableRequest $request
     *
     * @return Response
     */
    public function store(TableRequest $request)
    {
        $input                    = $request->all();
        $tableData                = [];
        $tableData['name']        = $input['name'];
        $tableData['title']       = $input['title'];
        $tableData['type']        = $input['type'];
        $tableData['description'] = $input['description'];
        $tableData['database_id'] = $input['database_id'];
        $tableData['relation']    = $input['relation'];
        $tableData['clone']       = $input['clone'];
        $tableData['publish']     = $input['publish'];
        $tableCount               = Table::count();
        $tableData['listorder']   = $tableCount + 1;
        $table                    = $this->tableRepository->create($tableData);
        $tablefields              = $input['tablefields'];
        $tableId                  = $table->id;
        $databaseId               = $table->database_id;
        $datas                    = [];
        foreach ($tablefields as $key => $value) {
            $data = [];
            if ($value['_remove_'] != '1') {
                $data['table_id']     = $tableId;
                $data['database_id']  = $databaseId;
                $data['name']         = $value['name'];
                $data['title']        = $value['title'];
                $data['field_type']   = $value['field_type'];
                $data['field_filter'] = $value['field_filter'];
                $data['column_width'] = $value['column_width'];
                $data['rw']           = $value['rw'];
                $data['form']         = $value['form'];
                $data['attr']         = $value['attr'];
                $data['description']  = $value['description'];
                $datas[]              = $data;
            }
        }
        $insertStatus = DB::table('table_fields')->insert($datas);
        if (empty($insertStatus)) {
            Flash::error('表格字段数据插入失败');
            return redirect(route('application.layouts.index'));
        }

        Flash::success(__('model_manage.tables.saved_success'));

        return Input::get('_previous_') ? redirect(Input::get('_previous_')) : redirect(route('model_manage.tables.index'));

    }

    /**
     * Display the specified Table.
     *
     * @param  int $id
     *
     * @return Response
     */
    public function show($id)
    {
        $table = $this->tableRepository->findWithoutFail($id);

        if (empty($table)) {
            Flash::error(__('model_manage.tables.not_found'));

            return redirect(route('model_manage.tables.index'));
        }

        return view('model_manage.tables.show')->with('table', $table);

    }

    /**
     * Show the form for editing the specified Table.
     *
     * @param  int $id
     *
     * @return Response
     */
    public function edit($id)
    {

        return Admin::content(function (Content $content) use ($id) {

            $content->header(__('model_manage.tables.edit_header'));
            $content->description(__('model_manage.tables.edit_description'));

            $content->body($this->form()->edit($id));
        });
    }

    /**
     * Update the specified Table in storage.
     *
     * @param  int              $id
     * @param TableRequest $request
     *
     * @return Response
     */
    public function update($id, TableRequest $request)
    {
        $table = $this->tableRepository->findWithoutFail($id);

        if (empty($table)) {
            Flash::error(__('model_manage.tables.not_found'));

            return redirect(route('model_manage.tables.index'));
        }
        $input                    = $request->all();
        $tableData                = [];
        $tableData['name']        = $input['name'];
        $tableData['title']       = $input['title'];
        $tableData['type']        = $input['type'];
        $tableData['description'] = $input['description'];
        $tableData['name']        = $input['name'];
        $tableData['database_id'] = $input['database_id'];
        $tableData['relation']    = $input['relation'];
        $tableData['clone']       = $input['clone'];
        $tableData['publish']     = $input['publish'];
        $table                    = $this->tableRepository->update($tableData, $id);
        $tablefields              = $input['tablefields'];
        $tableId                  = $table->id;
        $databaseId               = $table->database_id;
        $datas                    = [];
        foreach ($tablefields as $key => $value) {
            $data = [];
            if ($value['_remove_'] != '1') {
                $data['table_id']     = $tableId;
                $data['database_id']  = $databaseId;
                $data['name']         = $value['name'];
                $data['title']        = $value['title'];
                $data['field_type']   = $value['field_type'];
                $data['field_filter'] = $value['field_filter'];
                $data['column_width'] = $value['column_width'];
                $data['rw']           = $value['rw'];
                $data['form']         = $value['form'];
                $data['attr']         = $value['attr'];
                $data['clone']        = $value['clone'];
                $data['publish']      = $value['publish'];
                $data['description']  = $value['description'];
                $datas[]              = $data;
            }
        }
        DB::beginTransaction();
        try {
            DB::table('table_fields')->where('table_id', $id)->delete();
            DB::table('table_fields')->insert($datas);
            DB::commit();
        } catch (Exception $e) {
            //接收异常处理并回滚
            DB::rollBack();
            throw $e;
        }
        Flash::success(__('model_manage.tables.updated_success'));

        return Input::get('_previous_') ? redirect(Input::get('_previous_')) : redirect(route('model_manage.tables.index'));
    }

    /**
     * Remove the specified Table from storage.
     *
     * @param  int $id
     *
     * @return Response
     */
    public function destroy($id)
    {
        // 根据 `,` 判断传递过来的是单个id还是多个id
        if (substr_count($id, ',') >= 1) {
            $id = explode(",", $id);
        }

        // 如果是数组则进行批量删除
        if (is_array($id)) {
            if ($flag = $this->tableRepository->batchDelete('id', $id)) {

                return response()->json(['message' => __('model_manage.tables.deleted_success'), 'status' => $flag]);
            } else {
                return response()->json(['message' => __('base.deleted.error'), 'status' => $flag]);
            }
        }

        $table = $this->tableRepository->findWithoutFail($id);

        if (empty($table)) {
            Flash::error(__('model_manage.tables.not_found'));

            return redirect(route('model_manage.tables.index'));
        }

        if ($flag = $this->tableRepository->delete($id)) {

            return response()->json(['message' => __('model_manage.tables.deleted_success'), 'status' => $flag]);
        } else {
            return response()->json(['message' => __('base.deleted.error'), 'status' => $flag]);
        }
    }

    /**
     * [form description]
     * @return {[type]} [description]
     */
    protected function form()
    {
        return Admin::form(Table::class, function (Form $form) {

            $form->tab('基本信息', function (Form $form) {
                $form->display('id', 'ID');
                $databases = Database::pluck('title', 'id');
                $form->select('database_id', '所属库')->options($databases);
                $form->text('name', '表名');
                $form->text('title', '表别名');
                $types = [
                    1 => '分类数据',
                    2 => '实体数据',
                    3 => '实体资源',
                ];
                $form->select('type', '类型')->options($types)->default('1');

                $form->textarea('relation', '关系');
                $form->textarea('clone', '克隆');
                $form->textarea('publish', '发布');
                $form->textarea('description', '描述');
                // $form->display('created_at', __('base.created_at'));
                // $form->display('updated_at', __('base.updated_at'));
            })->tab('表字段管理', function (Form $form) {
                // 添加表单字段
                $form->hasMany('tablefields', '编辑表字段', function (Form\NestedForm $form) {

                    $form->text('name', '字段名');
                    $form->text('title', '字段别名');
                    // $tables = Table::pluck('title', 'id');
                    // $form->select('table_id', '表名')->options($tables);
                    $fieldType = [
                        'integer'  => 'integer',
                        'string'   => 'string',
                        'text'     => 'text',
                        'date'     => 'date',
                        'dateTime' => 'dateTime',
                        'char'     => 'char',
                        'year'     => 'year',
                        'boolean'  => 'boolean',
                        'float'    => 'float',
                        'array'    => 'array',
                    ];
                    $form->select('field_type', '字段属性')->options($fieldType);
                    $form->switch('field_filter', '视图过滤');
                    $form->text('column_width', '视图(宽度)');
                    $rw = [
                        'r'  => '只读',
                        'w'  => '只写',
                        'rw' => '读写',
                    ];
                    $form->radio('rw', '读写')->options($rw)->default('rw');
                    $formInput = [
                        'text'     => '文本框',
                        'select'   => '下拉框',
                        'radio'    => '单选框',
                        'checkbox' => '复选框',
                        'password' => '密码输入框',
                        'number'   => '数字输入框',
                        'textarea' => 'textarea输入框',
                        'editor'   => '富文本编辑框',
                        'image'    => '图片',
                        'url'      => 'url输入框',
                        'date'     => '日期输入框',
                        'datetime' => '日期时间输入框',
                        'mobile'   => '电话号码输入框',
                        'ip'       => 'ip输入框',
                        'email'    => 'email个数输入框',
                        'currency' => '货币输入框',
                        'rate'     => '比例输入框',
                        'color'    => '颜色选择框',
                    ];
                    $form->select('form', '表单输入')->options($formInput);
                    $indexs = [
                        '0' => '否',
                        '1' => '是',
                    ];
                    $form->radio('index', '索引')->options($indexs)->default(0);
                    $fieldType = [
                        'foreign' => 'foreign',
                        'options' => 'options',
                        'basic'   => 'basic',
                        'maps'    => 'maps',
                        'href'    => 'href',
                        'flow'    => 'flow',
                        'uuid'    => 'uuid',
                    ];
                    $form->select('type', '类型')->options($fieldType);
                    $form->text('attr', 'JSON编辑');
                    $form->text('clone', '克隆');
                    $form->text('publish', '发布');
                    $form->text('description', '说明');
                });
            });

        });
    }

    /**
     * [grid description]
     * @return {[type]} [description]
     */
    protected function grid()
    {
        return Admin::grid(Table::class, function (Grid $grid) {
            // 考虑是否需要scope和排序
            $grid->model()->orderBy('listorder', 'asc');

            // // 添加按钮
            // if (!\Gate::check('model_manage.tables.create')) {
            //     $grid->disableCreation();
            // }

            // // 编辑和删除按钮
            // $grid->actions(function ($actions) {
            //     // 编辑按钮
            //     if (!\Gate::check('model_manage.tables.edit')) {
            //         $actions->disableEdit();
            //     }
            //     // 删除按钮
            //     if (!\Gate::check('model_manage.tables.destroy')) {
            //         $actions->disableDelete();
            //     }
            // });

            // // 导出按钮
            // if (!\Gate::check('model_manage.tables.export')) {
            //     $grid->disableExport();
            // }

            // // 批量操作
            // $grid->tools(function ($tools) {
            //     $tools->batch(function ($batch) {
            //         // 批量删除按钮
            //         if (!\Gate::check('model_manage.tables.batch_destroy')) {
            //             $batch->disableDelete();
            //         }
            //     });
            // });

            // 添加按钮
            if (Admin::user()->cannot('model_manage.tables.create')) {
                $grid->disableCreation();
            }

            // 编辑和删除按钮
            $grid->actions(function ($actions) {
                $id = $actions->getKey();
                // 编辑按钮
                if (Admin::user()->cannot('model_manage.tables.edit')) {
                    $actions->disableEdit();
                }
                // 删除按钮
                if (Admin::user()->cannot('model_manage.tables.destroy')) {
                    $actions->disableDelete();
                }
                $url = route('model_manage.table_fields.index', ['table_id' => $id, '_t' => rand(100000000, 900000000)]);
                $actions->append('<a href="' . $url . '" title="编辑表字段">&nbsp;&nbsp;编辑表字段/&nbsp;&nbsp;</a>');
                // 克隆
                $actions->append('<a href="javascript:void(0);" title="克隆">&nbsp;&nbsp;克隆/&nbsp;&nbsp;</a>');
                //生成数据库表及 migrations文件
                $url =  route('model_manage.tables.migrate', ['table_id' => $id]);
                $actions->append('<a href="'.$url.'" title="生成迁移文件">&nbsp;&nbsp;生成迁移文件/&nbsp;&nbsp;</a>');
            });

            // 导出按钮
            if (Admin::user()->cannot('model_manage.tables.export')) {
                $grid->disableExport();
            }

            // 批量操作
            $grid->tools(function ($tools) {
                $tools->batch(function ($batch) {
                    // 批量删除按钮
                    if (Admin::user()->cannot('model_manage.tables.batch_destroy')) {
                        $batch->disableDelete();
                    }
                });
            });

            $grid->column('id', 'ID')->sortable();
            $grid->column('database.title', '库');
            $grid->column('name', '表名')->sortable();
            $grid->column('title', '表别名')->sortable();
            $grid->column('type', '类型')->display(function ($val) {
                switch ($val) {
                    case '1':
                        return '<span class="badge bg-green">分类数据</span>';
                        break;
                    case '2':
                        return '<span class="badge bg-green">实体数据</span>';
                        break;
                    case '3':
                        return '<span class="badge bg-green">实体资源</span>';
                        break;
                    default:
                        return '';
                        break;
                }
            });
            $grid->column('relation', '关系')->sortable();
            $grid->column('clone', '克隆')->sortable();
            $grid->column('publish', '发布')->sortable();
            $grid->column('description', '描述')->sortable()->display(function ($val) {
                if (!empty($val)) {
                    return Str::limit($val, 20);
                }
                return '';
            });

            /**
             * 过滤处理
             */
            $grid->filter(function ($filter) {
                // // 禁用id查询框
                // $filter->disableIdFilter();
                $filter->like('name', '名称');
                // 表格
                $tmpDatabases = Database::pluck('title', 'id');
                $filter->equal('database_id', '库')->select($tmpDatabases);
            });
        });
    }


    public function migrate(Request $request){
        $table_id = $request->get('table_id');
        $table_info = Table::with(['database'])->find($table_id);
        $table_fields = TableField::where('table_id',$table_id)->get();
        $class_name = ucfirst($table_info->name);
        $message    = '<div style="word-wrap: break-word;">';
        $message .= '生成Migration文件如下:<br>';
        $php_code = <<<EOT
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;

class Create{$class_name}Table extends Migration {

	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::connection('{$table_info->database->name}')->create('{$table_info->name}', function(Blueprint \$table)
		{
		    \$table->increments('id');
EOT;

        foreach ($table_fields as $table_field){
              if($table_field->type == 'maps'){
                  $real_table_info = Table::with(['database'])->where('name',$table_field->name.'s')->first();
                  if(empty($real_table_info)){
                      continue;
                  }
                  //生成关系表Migration
                  $rs = TableField::creatMapRelationTableMigration($table_info,$real_table_info);
                  $message .= $rs."<br>";
              }else{
                  $str = TableField::changeMigration($table_field);
                  $php_code .=  $str;
              }
        }

        $php_code .= "
        });
	}


	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::connection('{$table_info->database->name}')->drop('{$table_info->name}');
	}

}
";
        $file_name = 'migrations'.DIRECTORY_SEPARATOR.date("Y_m_d_His").'_create_'.$table_info->name.'_table.php';
        $rs = Storage::disk('local')->put($file_name, $php_code);
        $message .= storage_path('app'. DIRECTORY_SEPARATOR.$file_name)."<br>";
        $message .= '</div>';
        $success = new MessageBag([
            'title'   => '生成迁移文件',
            'message' => $message,
        ]);
        $shell = "cp -rf ".storage_path('app'. DIRECTORY_SEPARATOR.'migrations')."/* /home/www/migrations >> /data/wwwroot/default/migrations.log 2>&1 && cd /home/www/migrations >> /data/wwwroot/default/migrations.log 2>&1 && git add . >> /data/wwwroot/default/migrations.log 2>&1 && git commit -m 'migrations push git' >> /data/wwwroot/default/migrations.log 2>&1 && git push >> /data/wwwroot/default/migrations.log 2>&1";
        @exec($shell,$out);
        Log::info($shell);
        Log::info(var_export($out,TRUE));
        return back()->with(compact('success'));
    }


}
